package helper.com.exception;


import helper.com.res.AjaxResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.transaction.CannotCreateTransactionException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;

import java.util.List;

import static helper.com.exception.CustomExceptionType.*;

/**
 * @author zdh
 */
@ControllerAdvice
@Slf4j
public class WebExceptionHandler {

    /**
     * 非法参数异常
     */
    @ResponseStatus()
    @ExceptionHandler(IllegalArgumentException.class)
    @ResponseBody
    public AjaxResponse illegalArgumentException(IllegalArgumentException e) {
        log.error("错误类型为IllegalArgumentException : "+e);
        return AjaxResponse.error(ILLEGAL_ARGUMENT, ILLEGAL_ARGUMENT.getDesc()+": "+e.getMessage());
    }

    /**
     * JSR303数据校验异常
     */
    @ResponseStatus()
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public AjaxResponse methodArgumentNotValidException(MethodArgumentNotValidException e) {
        List<FieldError> fieldErrors = e.getBindingResult().getFieldErrors();
        StringBuilder stringBuilder=new StringBuilder();
        stringBuilder.append("错误信息: ");
        fieldErrors.forEach(fieldError -> {
            stringBuilder.append(fieldError.getField()+"-->").append(fieldError.getDefaultMessage())
                    .append(",");
        });
        log.error("错误类型为MethodArgumentNotValidException : "+stringBuilder.toString());
        return AjaxResponse.error(ILLEGAL_ARGUMENT,
                 stringBuilder.toString());
    }

    @ResponseStatus()
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public AjaxResponse exception(Exception e) {
        log.error("错误类型为Exception : "+e);
        return AjaxResponse.error(e.getMessage());
    }

    @ResponseStatus()
    @ExceptionHandler(CustomException.class)
    @ResponseBody
    public AjaxResponse customException(Exception e) {
        log.error("错误类型为customException : "+e);
        return AjaxResponse.error(e.getMessage());
    }

    @ResponseStatus()
    @ExceptionHandler(CannotCreateTransactionException.class)
    @ResponseBody
    public AjaxResponse cannotCreateTransactionException(CannotCreateTransactionException e) {
        log.error("错误类型为CannotCreateTransactionException : "+e);
        return AjaxResponse.error(INTERNAL_SERVER_ERROR, "数据库连接超时");
    }

    /**
     * 唯一索引重复异常
     */
    @ResponseStatus()
    @ExceptionHandler(DuplicateKeyException.class)
    @ResponseBody
    public AjaxResponse duplicateKeyException(Exception e) {
        String[] split = e.getCause().getMessage().split("\'");
        StringBuilder errBuilder=new StringBuilder();
        String err = errBuilder.append("字段: " + split[1] + " 发生了" + (split[3].equals("PRIMARY") ? "主键重复" : "唯一键重复") + "的错误").toString();
        log.error("错误类型为duplicateKeyException : {}",err);
        return AjaxResponse.error(CustomExceptionType.INTERNAL_SERVER_ERROR,err);
    }

    @ResponseStatus()
    @ExceptionHandler(NullPointerException.class)
    @ResponseBody
    public AjaxResponse nullPointerException(NullPointerException e) {
        log.error("错误类型为NullPointerException : {}",e);
        return AjaxResponse.error(NOT_FOUND);
    }
}
